package com.pn.taikao.config;

import com.pn.taikao.entity.User;
import com.pn.taikao.service.UserService;
import com.pn.taikao.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.Collections;
import java.util.List;

/**
 * JWT认证过滤器
 * 从请求头中提取JWT Token并验证，设置Spring Security认证上下文
 */
@Component
public class JwtAuthFilter extends OncePerRequestFilter {

    private static final Logger logger = LoggerFactory.getLogger(JwtAuthFilter.class);
    
    private final JwtUtil jwtUtil;
    private final UserService userService;

    public JwtAuthFilter(JwtUtil jwtUtil, UserService userService) {
        this.jwtUtil = jwtUtil;
        this.userService = userService;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, 
                                  FilterChain filterChain) throws ServletException, IOException {
        
        String authHeader = request.getHeader(HttpHeaders.AUTHORIZATION);
        
        if (StringUtils.hasText(authHeader) && authHeader.startsWith("Bearer ")) {
            String token = authHeader.substring(7);
            
            try {
                // 验证Token格式和签名
                Claims claims = jwtUtil.parseToken(token);
                
                // 检查Token是否过期
                if (jwtUtil.isTokenExpired(claims)) {
                    logger.debug("Token已过期: {}", request.getRequestURI());
                } else {
                    Long uid = claims.get("uid", Long.class);
                    String username = claims.get("username", String.class);
                    String role = claims.get("role", String.class);

                    if (uid != null && username != null && role != null) {
                        // 从数据库加载用户，确保用户状态最新
                        User user = userService.getById(uid);
                        if (user != null && "0".equals(user.getDelFlag())) {
                            // 用户存在且未删除
                            List<GrantedAuthority> authorities = Collections.singletonList(
                                    new SimpleGrantedAuthority("ROLE_" + role.toUpperCase())
                            );
                            
                            UsernamePasswordAuthenticationToken authentication =
                                    new UsernamePasswordAuthenticationToken(username, null, authorities);
                            authentication.setDetails(user); // 将用户信息存储到认证对象中
                            
                            SecurityContextHolder.getContext().setAuthentication(authentication);
                            logger.debug("JWT认证成功: userId={}, username={}, role={}", uid, username, role);
                        } else {
                            logger.debug("用户不存在或已被删除: userId={}", uid);
                        }
                    } else {
                        logger.debug("Token中缺少必要信息");
                    }
                }
            } catch (io.jsonwebtoken.ExpiredJwtException e) {
                logger.debug("Token已过期: {}", e.getMessage());
            } catch (io.jsonwebtoken.security.SignatureException e) {
                logger.debug("Token签名验证失败: {}", e.getMessage());
            } catch (io.jsonwebtoken.MalformedJwtException e) {
                logger.debug("Token格式错误: {}", e.getMessage());
            } catch (io.jsonwebtoken.UnsupportedJwtException e) {
                logger.debug("不支持的Token类型: {}", e.getMessage());
            } catch (Exception e) {
                logger.debug("Token验证失败: {}", e.getMessage());
            }
        }

        filterChain.doFilter(request, response);
    }
}
